package com.xinghanlaser.applet.base.common.handler;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;
import java.nio.charset.StandardCharsets;

/**
 * <p>
 *
 * <p>
 *
 * @author: mftuo 陀铭峰
 * @since: 2024/3/29 10:10
 */
public class MultiReadHttpServletRequest extends HttpServletRequestWrapper {
    private final byte[] requestBody;

    public MultiReadHttpServletRequest(HttpServletRequest request) throws IOException {
        super(request);
        requestBody = getRequestBody(request.getInputStream());
    }

    public String getRequestBodyAsString() {
        return new String(requestBody, StandardCharsets.UTF_8);
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        return new ServletInputStream() {
            private final ByteArrayInputStream inputStream = new ByteArrayInputStream(requestBody);

            @Override
            public int read() throws IOException {
                return inputStream.read();
            }

            @Override
            public boolean isFinished() {
                return false;
            }

            @Override
            public boolean isReady() {
                return true;
            }

            @Override
            public void setReadListener(ReadListener readListener) {
                // Not implemented as this is a simple ServletInputStream
            }
        };
    }

    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(this.getInputStream()));
    }

    private byte[] getRequestBody(ServletInputStream inputStream) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int bytesRead;
        while ((bytesRead = inputStream.read(buffer)) != -1) {
            baos.write(buffer, 0, bytesRead);
        }
        return baos.toByteArray();
    }
}
